<template>
  <div class="candidate-list">
    <h2 class="title">📋 候选人列表</h2>

    <div v-if="candidates.length === 0" class="empty">暂无候选人</div>

    <ul class="list">
      <li v-for="c in candidates" :key="c.id" class="candidate-item">
        <div class="info">
          <div class="candidate-line">
            <span class="candidate-index">#{{ c.id }}</span>
            <span class="candidate-name">{{ c.name }}</span>
          </div>
          <div class="votes">🗳️ {{ c.voteCount }} 票</div>
        </div>
        <button
          v-if="canVote"
          @click="voteFor(c.id)"
          class="btn"
          :disabled="hasVoted"
        >
          {{ hasVoted ? '已投票' : '投票' }}
        </button>
      </li>
    </ul>

    <div v-if="voteMsg" :class="['msg', voteMsg.includes('成功') ? 'success' : 'error']">
      {{ voteMsg }}
    </div>
  </div>
</template>

<script setup>
import { ref, watchEffect } from 'vue';
import { ethers } from 'ethers';
import { getContract } from '../utils/contract';

const candidates = ref([]);
const hasVoted = ref(false);
const voteMsg = ref('');
const canVote = ref(false);
const userAddress = ref('');

if (window.ethereum) {
  window.ethereum.request({ method: 'eth_accounts' }).then(accs => {
    userAddress.value = accs[0] || '';
    canVote.value = !!userAddress.value;
  });
}

async function loadCandidates() {
  const provider = new ethers.BrowserProvider(window.ethereum);
  const contract = getContract(provider);
  const count = await contract.candidatesCount();
  const arr = [];
  for (let i = 1; i <= Number(count); i++) {
    const c = await contract.getCandidate(i);
    arr.push({
      id: Number(c.id),
      name: c.name,
      voteCount: Number(c.voteCount)
    });
  }
  candidates.value = arr;

  if (userAddress.value) {
    hasVoted.value = await contract.voters(userAddress.value);
  }
}

async function voteFor(id) {
  voteMsg.value = '';
  try {
    const provider = new ethers.BrowserProvider(window.ethereum);
    const signer = await provider.getSigner();
    const contract = getContract(signer);
    const tx = await contract.vote(id);
    voteMsg.value = '⏳ 交易已发送，等待确认...';
    await tx.wait();
    voteMsg.value = '✅ 投票成功！';
    loadCandidates();
    hasVoted.value = true;
  } catch (e) {
    voteMsg.value = '❌ ' + (e.info?.error?.message || e.message || '投票失败');
  }
}

watchEffect(() => {
  if (userAddress.value) loadCandidates();
});
</script>

<style scoped>
.title {
  font-size: 1.15rem;
  font-weight: 600;
  color: #25355a;
  margin-bottom: 20px;
}

.empty {
  padding: 16px;
  text-align: center;
  color: #7480a1;
  background-color: #f7f9fb;
  border-radius: 12px;
  font-size: 15px;
}

/* 列表样式：极简，留白 */
.list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.candidate-item {
  background: #fff;
  border-radius: 12px;
  border: 1px solid #e5e9ef;
  box-shadow: 0 2px 10px rgba(50,60,90,0.08);
  padding: 15px 18px;
  margin-bottom: 14px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  transition: box-shadow 0.17s, border-color 0.17s;
}
.candidate-item:hover {
  box-shadow: 0 6px 18px rgba(50,60,90,0.11);
  border-color: #a5b8d8;
}

/* 信息排版更清晰 */
.info {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 15px;
}
.candidate-line {
  display: flex;
  align-items: center;
  gap: 10px;
}
.candidate-index {
  font-weight: 600;
  color: #27468a;
  width: 34px;
  display: inline-block;
}
.candidate-name {
  font-weight: 500;
  color: #25355a;
}

.votes {
  color: #3a517d;
  font-size: 14px;
  margin-top: 2px;
}

/* 商务风按钮 */
.btn {
  background-color: #27468a;
  color: #fff;
  padding: 8px 20px;
  border: 1px solid #27468a;
  border-radius: 7px;
  font-size: 15px;
  font-weight: 500;
  box-shadow: 0 1px 3px rgba(39,70,138,0.06);
  cursor: pointer;
  transition: background 0.18s, border 0.18s, color 0.18s, box-shadow 0.16s;
}
.btn:disabled {
  background: #c2c8d6;
  color: #ffffffcc;
  border-color: #c2c8d6;
  cursor: not-allowed;
}
.btn:hover:enabled {
  background: #1d335e;
  border-color: #1d335e;
}

/* 状态消息 */
.msg {
  margin-top: 18px;
  font-size: 15px;
  text-align: center;
}
.success {
  color: #298f5b;
}
.error {
  color: #c23030;
}

/* 移动端适配 */
@media (max-width: 640px) {
  .title { font-size: 1.01rem; margin-bottom: 12px; }
  .candidate-item { padding: 10px 7px; margin-bottom: 8px; }
  .candidate-index { width: 28px; font-size: 0.98em; }
  .btn { font-size: 13px; padding: 6px 11px; }
}
</style>
